﻿using de.wolfmarco.pas.Shared.MessageBoxes;
using System;
using System.Security.Cryptography;
using System.Text;

namespace de.wolfmarco.pas.Shared.Cryptography
{
    public class ProtectedString
    {
        public ProtectedString()
        {
        }

        public string Protect()
        {
            Value = Protect(Value, Encoding, Entropy, Scope);
            return Value;
        }

        public string UnProtect()
        {
            Value = UnProtect(Value, Encoding, Entropy, Scope);
            return Value;
        }

        #region PROPERTIES

        private Encoding encoding = Encoding.Unicode;
        public Encoding Encoding
        {
            get { return encoding; }
            set { encoding = value; }
        }

        private string value;
        public string Value
        {
            get { return value; }
            set { this.value = value; }
        }


        private byte[] entropy = Encoding.Unicode.GetBytes("PASentropy");
        public byte[] Entropy
        {
            get { return entropy; }
            set { entropy = value; }
        }

        private DataProtectionScope scope = DataProtectionScope.CurrentUser;
        public DataProtectionScope Scope
        {
            get { return scope; }
            set { scope = value; }
        }

        #endregion PROPERTIES

        #region PROTECT & UNPROTECT

        public static string Protect(string toProtect, Encoding encoding, byte[] entropy, DataProtectionScope? scope)
        {
            #region VALIDATION

            if (String.IsNullOrEmpty(toProtect))
                return String.Empty;

            if (encoding == null)
                encoding = Encoding.Unicode;

            if (scope == null)
                scope = DataProtectionScope.CurrentUser;

            #endregion VALIDATION

            try
            {
                byte[] unProtectedBytes;
                byte[] protectedBytes;
                string protectedString;

                unProtectedBytes = encoding.GetBytes(toProtect);
                protectedBytes = ProtectedData.Protect(unProtectedBytes, entropy, scope.Value);
                protectedString = System.Convert.ToBase64String(protectedBytes);

                return protectedString;
            }
            catch (Exception exc)
            {
                PASMessageBox.ShowException(exc);
                return String.Empty;
            }
        }

        public static string UnProtect(string toUnProtect, Encoding encoding, byte[] entropy, DataProtectionScope? scope)
        {
            #region VALIDATION

            if (String.IsNullOrEmpty(toUnProtect))
                return String.Empty;

            if (encoding == null)
                encoding = Encoding.Unicode;

            if (scope==null)
                scope = DataProtectionScope.CurrentUser;

            #endregion VALIDATION

            try
            {
                byte[] protectedBytes;
                byte[] unProtectedBytes;
                string unProtectedString;

                protectedBytes = System.Convert.FromBase64String(toUnProtect);
                unProtectedBytes = ProtectedData.Unprotect(protectedBytes, entropy, scope.Value);
                unProtectedString = encoding.GetString(unProtectedBytes);

                return unProtectedString;
            }
            catch (Exception exc)
            {
                PASMessageBox.ShowException(exc);
                return String.Empty;
            }
        }

        #endregion PROTECT & UNPROTECT
    }
}
